package top.ninwoo.weixingsim.service.impl;

import top.ninwoo.weixingsim.entity.SimData;
import top.ninwoo.weixingsim.entity.WeiXingData;
import top.ninwoo.weixingsim.service.Toponet;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class ToponetImpl implements Toponet {

    @Override
    public String[] getAppNames(List<WeiXingData> weiXingDataList) {
        //先判断有多少个docker容器，并生成相对应的ovs
        int n = weiXingDataList.size();
        //创建docker容器和一个ovs的数组
        String[] appNames = new String[n+1];
        for(int j=0;j<n;j++){
            appNames[j] = weiXingDataList.get(j).getName();
        }
        appNames[n] = "br:"+ "ovs";

        return appNames;
    }

    @Override
    public int[][] getTopology(List<WeiXingData> weiXingDataList, SimData simData) {
        int n = weiXingDataList.size();
        int[][] topu = new int[n+1][n+1];
        //先将docker容器和ovs相连如：app1连br:ovs,app2连br:ovs
        for (int i = 0; i < n; i++) {
            topu[n][i] = 1;
        }
        //判断docker之间是否相通
        for(int a=0;a<n;a++){
            for(int b=a+1;b<n;b++){
                //通过距离来判断
                double channelCapacity = this.channelCapacity(weiXingDataList.get(a),weiXingDataList.get(b),simData);
                if(channelCapacity>=simData.getC0()){
                    topu[b][a] = 1;
                }
            }
        }
        return topu;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    @Override
    public Double distance(WeiXingData a, WeiXingData b) {
        Double r;
        r = Math.sqrt(Math.pow(a.getXaxis()-b.getXaxis(),2)+Math.pow(a.getYaxis()-b.getYaxis(),2)+Math.pow(a.getZaxis()-b.getZaxis(),2));
        return r;
    }

    @Override
    public Double channelCapacity(WeiXingData a, WeiXingData b, SimData sd) {
        double r = this.distance(a, b);
        double channelCapacity;

        channelCapacity = sd.getBandwidth()*Math.log(1+(sd.ptGtGr()/(Math.pow(4*Math.PI*r*sd.getJiange()/sd.getLamda(),2)*sd.n0B())))/Math.log(2);

        return channelCapacity;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    @Override
    public void history(String[] appNames, int[][] topo) {
        File file1 = new File("C:\\WorkSpace\\test\\history.txt");
        try {
            FileWriter fw = new FileWriter(file1,true);
            BufferedWriter bw = new BufferedWriter(fw);

            //先写上日期标记
            SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
            Date d= new Date();
            String str = sdf.format(d);
            bw.write(str + "开始的拓扑结构"+ "\n");

            //todo 需要设计排版
            int num = appNames.length;
            int[][] logic = new int[num][num];
            for(int i = 0; i<num;i++){
                for(int m =0;m<num;m++){
                    logic[i][m] = topo[i+num][m+num];
                    bw.write(logic[i][m] + " ");
                    bw.flush();
                }
                bw.write("\n" );
                bw.flush();
            }
            bw.close();
            fw.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void delHistory() {
        File file = new File("C:\\WorkSpace\\test\\history.txt");
        if (file.exists()) {
            file.delete();
        }
    }
}

